﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using WP7Client.ServerManager;
using WP7Client.Helpers;
using MSH.Common.DAO.Results;
using System.Collections.ObjectModel;
using MSH.Common.DAO;
using MSH.Common.Classes;
using WP7Client.Managers;
using GalaSoft.MvvmLight.Command;

namespace WP7Client.Controller
{
    public class PeopleNearbyController : BaseController
    {

        #region Get&Set

        public ICommand AddFriendCommand
        {
            get;
            internal set;
        }

        public ICommand ChatCommand
        {
            get;
            internal set;
        }

        public ICommand ShowProfileCommand
        {
            get;
            internal set;
        }

        public ICommand ShowMapCommand
        {
            get;
            internal set;
        }

        public ICommand FriendNotificationCommand
        {
            get;
            internal set;
        }

        private ObservableCollection<PersonNearby> _PeopleNearby = new ObservableCollection<PersonNearby>();
        public ObservableCollection<PersonNearby> PeopleNearby
        {
            get { return _PeopleNearby; }
            set
            {
                _PeopleNearby = value;
                OnPropertyChanged("PeopleNearby");
            }
        }

        private ObservableCollection<PersonNearby> _FriendsNearby = new ObservableCollection<PersonNearby>();
        public ObservableCollection<PersonNearby> FriendsNearby
        {
            get { return _FriendsNearby; }
            set
            {
                _FriendsNearby = value;
                OnPropertyChanged("FriendsNearby");
            }
        }
        #endregion

        public PeopleNearbyController()
        {
            ShowProfileCommand = new RelayCommand<String>(DoShowProfile);
            ChatCommand = new RelayCommand<String>(Chat);
            AddFriendCommand = new RelayCommand<String>(SendFriendInvitation);
            ShowMapCommand = new RelayCommand(ShowMap);
            FriendNotificationCommand = new RelayCommand<String>(ShowFriendNotification);
        }

        /// <summary>
        /// Nodig een gebruiker uit de buurt uit als vriend
        /// </summary>
        /// <param name="username">Gebruikersnaam van de gebruiker in de buurt</param>
        public void SendFriendInvitation(String username)
        {
            Loading = true;
            HttpGet inviteFriendHttpGet = new HttpGet(String.Format(GlobalHelper.Url + "AddFriend/{0}/{1}", UserHelper.Token, username), typeof(AddFriendResult));
            inviteFriendHttpGet.FinishedGet += inviteFriendHttpGet_FinishedGet;
        }

        /// <summary>
        /// Laat de pagina zien waarop de locatie notificatie van een vriend te zien is
        /// </summary>
        /// <param name="username">Gebruikersnaam van de vriend</param>
        private void ShowFriendNotification(String username)
        {
            ControllerHelper.FriendNotificationController.Load(username);
            NavigationHelper.NavigateTo("/UserInterface/Pages/FriendNotificationPage.xaml");
        }

        private void inviteFriendHttpGet_FinishedGet(Object sender, EventArgs e)
        {
            try
            {
                HttpGet get = sender as HttpGet;
                if (get != null && (get.resultObject as AddFriendResult) != null)
                {
                    AddFriendResult result = get.resultObject as AddFriendResult;

                    if (result.TokenValidationResult == TokenValidationResultEnum.Valid)
                    {
                        switch (result.Result)
                        {
                            case AddFriendResultEnum.FriendAlreadyRegistered:
                                GlobalHelper.ShowMessage("Error", "Person is already a friend of yours or you´ve already received/sent an invitation to this person.");
                                break;
                            case AddFriendResultEnum.Succes:
                                GlobalHelper.ShowMessage("", "Invitation has been sent.");
                                break;
                            case AddFriendResultEnum.UserNotExists:
                                break;
                        }
                    }
                    else
                    {

                    }
                }
            }
            catch (Exception ex) { }
            finally { Loading = false; }
        }

        public override void Update()
        {
            base.Update();
            GetPeopleNearby();
        }

        /// <summary>
        /// Haal een lijst op met gebruikers die in de buurt zijn
        /// </summary>
        private void GetPeopleNearby()
        {
            Loading = true;
            HttpGet peopleNearbyHttpGet = new HttpGet(String.Format(GlobalHelper.Url + "GetPeopleNearby/{0}/{1}", UserHelper.Token, ControllerHelper.SettingController.PeopleNearbyRange), typeof(GetPeopleNearbyResult));
            peopleNearbyHttpGet.FinishedGet += new EventHandler(peopleNearbyHttpGet_FinishedGet);
        }

        private void peopleNearbyHttpGet_FinishedGet(object sender, EventArgs e)
        {
            try
            {
                HttpGet get = sender as HttpGet;
                if (get == null || get.resultObject == null)
                    return;

                GetPeopleNearbyResult result = ((GetPeopleNearbyResult)get.resultObject);
                
                if (result == null)
                    throw new Exception("No result received.");

                if(result.People == null)
                    throw new Exception("no result list.");

                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    PeopleNearby.Clear();
                    FriendsNearby.Clear();

                    foreach (PersonNearby person in result.People)
                    {
                        if (person.LastSeenTimestamp != null && person.LastSeenTimestamp != new DateTime())
                        {
                            DateTime? oldTimeStamp = person.LastSeenTimestamp;
                            DateTime timeStamp = new DateTime(oldTimeStamp.Value.Year, oldTimeStamp.Value.Month, oldTimeStamp.Value.Day, oldTimeStamp.Value.Hour, oldTimeStamp.Value.Minute, oldTimeStamp.Value.Second, oldTimeStamp.Value.Millisecond, DateTimeKind.Utc);
                            person.LastSeenTimestamp = timeStamp.ToLocalTime();
                        }

                        if (person.isFriend)
                            FriendsNearby.Add(person);
                        else
                            PeopleNearby.Add(person);

                        DeterminePersonsLocation(person);
                    }
                    ControllerHelper.OverviewController.PeopleNearbyCount = String.Format("({0})",result.People.Count);
                    OnPropertyChanged("PeopleNearby");
                    OnPropertyChanged("FriendsNearby");
                });
            }
            catch (Exception ex)
            {

            }
            finally
            {
                Loading = false;
            }
        }

        /// <summary>
        /// Maak een locatie string aan de hand van de eigen locatie
        /// </summary>
        /// <param name="person">Gebruiker die in de buurt is</param>
        private void DeterminePersonsLocation(PersonNearby person)
        {
            if (person == null)
                return;

            UserLocationData currentLocationData = LocationManager.CurrentLocationData;
            String displayText = "";
            if (person.Distance != 0)
            {
                double distance = person.Distance;
                if (distance < 1)
                {
                    distance *= 1000;
                    if (distance < 1)
                    {
                        distance *= 1000;
                        AppendDisplayText(ref displayText, ((Convert.ToInt32(distance)).ToString() + " cm"));
                    }
                    else
                        AppendDisplayText(ref displayText, ((Convert.ToInt32(distance)).ToString() + " m"));
                }
                else
                    AppendDisplayText(ref displayText, ((Convert.ToInt32(distance)).ToString() + " km"));
                
            }
            if (!String.IsNullOrEmpty(person.AddressLine))
                AppendDisplayText(ref displayText, person.AddressLine);
            if (currentLocationData != null)
            {
                if (!String.IsNullOrEmpty(person.Locality) && person.Locality != currentLocationData.Locality)
                    AppendDisplayText(ref displayText, person.Locality);
                if (!String.IsNullOrEmpty(person.CountryRegion) && person.CountryRegion != currentLocationData.CountryRegion)
                    AppendDisplayText(ref displayText, "\n" + person.CountryRegion);
            }
            else
            {
                if (!String.IsNullOrEmpty(person.Locality))
                    AppendDisplayText(ref displayText, person.Locality);
                if (!String.IsNullOrEmpty(person.CountryRegion))
                    AppendDisplayText(ref displayText, "\n" + person.CountryRegion);
            }
         
            person.DisplayablePosition = displayText;
        }

        private void AppendDisplayText(ref String displaytext, String text)
        {
            if (displaytext == null || text == null)
                return;

            if (displaytext == String.Empty)
                displaytext = text;
            else
                displaytext += (", " + text);
        }
        
        /// <summary>
        /// Toon het profiel van de gebruiker
        /// </summary>
        /// <param name="username">Gebruikersnaam van de gebruiker in de buurt</param>
        private void DoShowProfile(String username)
        {
            NavigationHelper.NavigateTo(String.Format("/UserInterface/Pages/ProfilePage.xaml?username={0}", username));
        }

        /// <summary>
        /// Chat met de gebruiker
        /// </summary>
        /// <param name="username">Gebruikersnaam van de gebruiker in de buurt</param>
        private void Chat(String username)
        {
            ControllerHelper.ConversationsController.ChatWith(username);
        }

        /// <summary>
        /// Toon de gebruikers op de map
        /// </summary>
        private void ShowMap()
        {
            NavigationHelper.NavigateTo("/UserInterface/Pages/MapPage.xaml?MapMode=PeopleNearby");
        }
    }
}
